home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / • Obsolete⁄Unsupported / MIDI Management Tools / MIDI Sample Applications / SimpleKeyƒ / SimpleKey.p < prev    next >
Encoding:
Text File  |  1993-06-09  |  7.1 KB  |  333 lines  |  [TEXT/MPS ]

  1. {------------------------------------------------------------------------------
  2. #
  3. #    SimpleKey
  4. #        - a sample MIDI Management Tools application
  5. #
  6. #    SimpleKey.p    -    Pascal Source
  7. #
  8. #    Copyright © 1988-1989 Apple Computer, Inc.
  9. #    All rights reserved.
  10. #
  11. #    Version:    1.0
  12. #
  13. #    SimpleKey is a sample application that uses the MIDI Management
  14. #    Tools.  It displays a small piano keyboard on the screen and
  15. #    interprets mouse clicks to send MIDI events.  It also has a
  16. #    scroll bar for changing the channel that these events are sent on.
  17. #
  18. #    Please be familiar with both the MIDI Management Tools and MIDI
  19. #    in general before trying to understand this code.  
  20. #
  21. #    This application is an example of how to call the MIDI Management
  22. #    tools.  It is not meant as an example of a good Macintosh
  23. #    application; it is NOT a template. It is NOT intended to be 
  24. #    used as a foundation for the next world-class, best-selling, 
  25. #    600K application. A stick figure drawing of the human body may 
  26. #    be a good example of the form for a painting, but that does not 
  27. #    mean it should be used as the basis for the next Mona Lisa.
  28. #
  29. #    This code also makes use of a small library called OneDialog.
  30. #    This is a small set of routines that are only useful for very 
  31. #    simple applications.  Again, it isn't a good general library.
  32. #    You probably don't want to use it.
  33. #
  34. ------------------------------------------------------------------------------}
  35.  
  36. PROGRAM SimpleKey;
  37.  
  38.     USES
  39.         MemTypes,
  40.         QuickDraw,
  41.         OSIntf,
  42.         ToolIntf,
  43.         PackIntf,
  44.         MIDI,
  45.         OneDialog;
  46.  
  47.     CONST
  48.         DialogRes        = 500;
  49.  
  50.         { Dialog Item Numbers }
  51.         NullItem        = 0;
  52.         QuitItem        = 1;
  53.         SilenceItem        = 2;
  54.         KeyboardItem    = 3;
  55.         ChannelItem        = 4;
  56.         ChannelTextItem    = 5;
  57.         
  58.         mySignature        ='mgL9';
  59.         
  60.         myIcon            = 128;
  61.  
  62.     VAR
  63.         Channel            : INTEGER;
  64.         PortRefNum        : INTEGER;
  65.         OurMenu            : MenuHandle;
  66.  
  67.  
  68.  
  69.     PROCEDURE ReportOS(err: OSErr; who: Str255);
  70.         VAR
  71.             errNumber    : Str255;
  72.         BEGIN
  73.             IF err <> NoErr THEN BEGIN
  74.                 NumToString(err, errNumber);
  75.                 Message(CONCAT(who, ': ', errNumber), ChannelTextItem);
  76.             END;
  77.         END;
  78.     
  79.  
  80.  
  81.     PROCEDURE WriteNote(note: INTEGER; onoff: BOOLEAN);
  82.         VAR
  83.             output        : MIDIPacket;
  84.         BEGIN
  85.             WITH output DO BEGIN
  86.                 flags := midiMsgType + midiTimeStampCurrent + midiNoCont;
  87.                 len := 9;
  88.                 tStamp := 0;
  89.                 
  90.                 IF onoff THEN
  91.                     data[0] := $90 + Channel - 1
  92.                 ELSE
  93.                     data[0] := $80 + Channel - 1;
  94.                 data[1] := note;
  95.                 data[2] := 64;
  96.             END;
  97.             
  98.             ReportOS(MIDIWritePacket(PortRefNum, @output), 'MIDIWritePacket');
  99.         END;
  100.  
  101.  
  102.  
  103.  
  104.     PROCEDURE SilenceAll;
  105.         VAR
  106.             n            : INTEGER;
  107.             output        : MIDIPacket;
  108.         BEGIN
  109.             WITH output DO BEGIN
  110.                 flags := midiMsgType + midiTimeStampCurrent + midiNoCont;
  111.                 len := 9;
  112.                 tStamp := 0;
  113.                 
  114.                 data[0] := $B0 + Channel - 1;
  115.                 data[1] := 123;
  116.                 data[2] := 0;
  117.             END;
  118.             
  119.             ReportOS(MIDIWritePacket(PortRefNum, @output), 'MIDIWritePacket');
  120.  
  121.             FOR n := 0 TO 127 DO
  122.                 WriteNote(n, FALSE);
  123.         END;
  124.  
  125.         
  126.     PROCEDURE Keyhit;
  127.         VAR
  128.             itemType        : INTEGER;
  129.             itemHdl            : Handle;
  130.             itemRect        : Rect;
  131.             pointHit        : Point;
  132.             width, height    : INTEGER;
  133.             octave, note    : INTEGER;
  134.             oldNote            : INTEGER;                    
  135.         BEGIN
  136.             GetDItem(TheDialog, KeyboardItem, itemType, itemHdl, itemRect);
  137.             oldNote := -1;
  138.             
  139.             WHILE StillDown DO BEGIN
  140.                 GetMouse(pointHit);
  141.                 octave := (pointHit.h - itemRect.left) DIV 49;
  142.                 IF (itemRect.bottom - pointHit.v) < 12 THEN BEGIN
  143.                     note := ((pointHit.h - itemRect.left) - (49 * octave)) DIV 7;
  144.                     note := note * 2;
  145.                     IF note >= 4 THEN note := note - 1;
  146.                     IF note >= 9 THEN note := note - 1;
  147.                 END ELSE BEGIN
  148.                     note := ((pointHit.h - itemRect.left) - (49 * octave) - 3) DIV 11;
  149.                     note := note * 2 + 1;
  150.                     IF note >= 3 THEN note := note + 1;
  151.                     IF note >= 8 THEN note := note + 1;
  152.                 END;
  153.  
  154.                 note := note + 12 * octave + 21;
  155.                 IF note <> oldNote THEN BEGIN
  156.                     IF oldNote <> -1 THEN
  157.                         WriteNote(oldNote, FALSE);
  158.                     WriteNote(note, TRUE);
  159.                     oldNote := note;
  160.                 END;
  161.             END;
  162.             
  163.             IF oldNote <> -1 THEN
  164.                 WriteNote(oldNote, FALSE);
  165.         END;
  166.  
  167.  
  168.  
  169.  
  170.     PROCEDURE SetChannel;
  171.         VAR
  172.             ChannelText        : Str255;
  173.         BEGIN
  174.             DetermineValue(Channel, ChannelItem);
  175.             NumToString(Channel, ChannelText);
  176.             Message(CONCAT('Channel: ', ChannelText), ChannelTextItem);
  177.         END;        
  178.  
  179.  
  180.  
  181.     PROCEDURE StartUp;
  182.         VAR
  183.             init        : MIDIPortParams;
  184.         BEGIN
  185.             IF SndDispVersion(midiToolNum) <> 0 THEN
  186.                 Message('MIDI Manager isn''t there!', ChannelTextItem);
  187.                 { This should really quit gracefully here
  188.                     and not call any other MIDI Manager Functions. }
  189.             
  190.             ReportOS(MIDISignIn(mySignature,
  191.                                 0,
  192.                                 GetResource('ICN#', myIcon),
  193.                                 'Simple Keyboard'),
  194.                         'MIDISignIn');
  195.  
  196.             WITH init DO BEGIN
  197.                 portID        := 'out ';
  198.                 portType     := midiPortTypeOutput;
  199.                 timeBase    := 0;
  200.                 offsetTime     := midiGetNothing;
  201.                 readHook     := NIL;
  202.                 refCon        := 0;
  203.                 name         := 'notes';
  204.             END;
  205.             ReportOS(MIDIAddPort(mySignature, 300, PortRefNum, @init), 'AddDataPort');
  206.  
  207.             ClearMenuBar;
  208.             OurMenu := GetMenu(128);
  209.             InsertMenu(OurMenu, 0);
  210.             AddResMenu(OurMenu, 'DRVR');
  211.             DrawMenuBar;
  212.  
  213.         END;
  214.  
  215.  
  216.  
  217.     PROCEDURE ShutDown;
  218.         BEGIN
  219.             DeleteMenu(128);
  220.             DisposHandle(Handle(OurMenu));
  221.             DrawMenuBar;
  222.  
  223.             MIDISignOut(mySignature);
  224.         END;
  225.  
  226.  
  227.  
  228. {--- Dialog Management Routines ---}
  229.     PROCEDURE StartDialog;
  230.         VAR
  231.             item        : INTEGER;
  232.             whoCares    : BOOLEAN;
  233.             
  234.         BEGIN
  235.             TheDialog := GetNewDialog(DialogRes, NIL, Pointer(-1));
  236.             SetPort(TheDialog);
  237.             
  238.             FixScrollBar(ChannelItem, 1, 1);
  239.             SetChannel;
  240.         END;
  241.  
  242.  
  243.  
  244.     PROCEDURE RunDialog;
  245.         VAR
  246.             anEvent        : EventRecord;
  247.             itemHit        : INTEGER;
  248.             done        : BOOLEAN;
  249.             whichWindow    : WindowPtr;
  250.             boundry        : Rect;
  251.             item        : LONGINT;
  252.             daName        : Str255;
  253.             daRefNum    : INTEGER;
  254.         BEGIN
  255.             ShowWindow(TheDialog);
  256.  
  257.             done := FALSE;
  258.             REPEAT
  259.                 IF WaitNextEvent(everyEvent, anEvent, 50, NIL) THEN
  260.                 {IF GetNextEvent(everyEvent, anEvent) THEN}
  261.                     IF IsDialogEvent(anEvent) THEN
  262.                         IF DialogSelect(anEvent, TheDialog, itemHit) THEN
  263.                             CASE itemHit OF
  264.                                 QuitItem:        done := TRUE;
  265.                                 SilenceItem:    SilenceAll;
  266.                                 KeyboardItem:    Keyhit;
  267.                                 ChannelItem:    SetChannel;
  268.             
  269.                                 OTHERWISE
  270.                                     SysBeep(2);
  271.                             END
  272.                         ELSE BEGIN END
  273.                     ELSE
  274.                         CASE FindWindow(anEvent.where, whichWindow) OF
  275.                             inMenuBar:
  276.                                 BEGIN
  277.                                     item := MenuSelect(anEvent.where);
  278.                                     IF HiWrd(item) = 128 THEN BEGIN
  279.                                         GetItem(GetMHandle(128), LoWrd(item), daName);
  280.                                         daRefNum := OpenDeskAcc(daName);
  281.                                     END;
  282.                                     HiLiteMenu(0);
  283.                                 END;
  284.                                 
  285.                             inSysWindow:
  286.                                 SystemClick(anEvent, whichWindow);
  287.                                 
  288.                             inGoAway:
  289.                                 IF TrackGoAway(whichWindow, anEvent.where) THEN
  290.                                     done := TRUE;
  291.                                     
  292.                             inDrag:
  293.                                 BEGIN
  294.                                     WITH screenBits.bounds DO
  295.                                         SetRect(boundry, 4, 24, right - 4, bottom - 4);
  296.                                     DragWindow(whichWindow, anEvent.where, boundry);
  297.                                 END;
  298.                         END
  299.             UNTIL done;
  300.         END;
  301.  
  302.  
  303.  
  304.     PROCEDURE StopDialog;
  305.         BEGIN
  306.             HideWindow(TheDialog);
  307.             DisposDialog(TheDialog);
  308.         END;
  309.  
  310.  
  311.  
  312.     PROCEDURE InitThings;
  313.         BEGIN
  314.             InitGraf(@thePort);
  315.             InitFonts;
  316.             InitWindows;
  317.             InitMenus;
  318.             TEInit;
  319.             InitDialogs(NIL);
  320.             FlushEvents(everyEvent, 0);
  321.             InitCursor;
  322.         END;
  323.  
  324.  
  325.  
  326.     BEGIN
  327.         InitThings;
  328.         StartDialog;
  329.         StartUp;
  330.         RunDialog;
  331.         ShutDown;
  332.         StopDialog;
  333.     END.